#!/usr/bin/env python
# stoker_wake: Implementation of Stoker "wake" command
#
# Author:   Mike Murphy (mamurph@cs.clemson.edu)
# Revision: 8 September 2008
#
#   Copyright 2007-2008 Clemson University
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# This material is based upon work supported under a National Science
# Foundation Graduate Research Fellowship. Any opinions, findings,
# conclusions or recommendations expressed in this publication are those of
# the author(s) and do not necessarily reflect the views of the National
# Science Foundation.

from time import sleep
import stoker_base, wake
from stoker_defines import CFG_WOL_BCAST_ADDR, CFG_WOL_BCAST_PORT, \
   CFG_WOL_TRIES, DFLT_WOL_BCAST_ADDR, DFLT_WOL_BCAST_PORT, DFLT_WOL_TRIES, \
   CFG_WOL_DELAY, DFLT_WOL_DELAY
from stoker_messages import MSG_UNRESOLVED_MAC

class WakeCommand(stoker_base.CommandObjectBase):
   def __init__(self, stoker_config, opts, args, target, extra):
      stoker_base.CommandObjectBase.__init__(self, stoker_config, opts, args, \
                                             target, extra)
      mac_parts = self.target.split(':')
      self.mac = []
      if len(mac_parts) == 6:
         for part in mac_parts:
            try:
               self.mac.append(int(part, 16))
            except Exception:
               self.mac = []
               break
            else:
               # Sanity check
               if self.mac[-1] < 0 or self.mac[-1] > 255:
                  self.mac = []
                  break
      #
      self.port = \
         int(stoker_config.getParam(CFG_WOL_BCAST_PORT, DFLT_WOL_BCAST_PORT))
      self.tries = int(stoker_config.getParam(CFG_WOL_TRIES, DFLT_WOL_TRIES))
      self.broadcast = \
            stoker_config.getParam(CFG_WOL_BCAST_ADDR, DFLT_WOL_BCAST_ADDR)
      self.delay = int(stoker_config.getParam(CFG_WOL_DELAY, DFLT_WOL_DELAY))
      for opt, val in self.opts:
         if opt in ('-b', '--broadcast'):
            self.broadcast = val
         elif opt in ('-p', '--port'):
            self.broadcast = int(val)
         elif opt in ('-t', '--tries'):
            self.tries = int(val)
         elif opt in ('-d', '--delay'):
            self.delay = int(val)
   #
   def execute(self, stdin=''):
      code = 0
      err = ''
      if len(self.mac) != 6:
         code = 2
         err = 'wake: ' + MSG_UNRESOLVED_MAC % (self.target)
      else:
         for n in range(0, self.tries):
            try:
               wake.wol(self.mac, (self.broadcast, self.port))
               if self.delay > 0:
                  sleep(self.delay)
            except Exception, message:
               code = 1
               err += str(message)
               break
      return (code, '', err)
   #
